
import { _decorator, Component, Node, instantiate, v3, SpriteFrame, tween, director, EventTouch, Label, macro, view, randomRange, randomRangeInt, Sprite, v4, Color } from 'cc';
import { Card } from './Card';
import { CardGroup } from './CardGroup';
import { CardGroupParent } from './CardGroupParent';
import GameAllData from './GameAllData';
import { PlayGroup } from './PlayGroup';
import { PlayGroupAi } from './PlayGroupAi';
import GameFun from './tool/GameFun';
import GameManager from './tool/GameManager';
import LocalStorageMgr from './tool/LocalStorageMgr';
import { SoundEffect } from './tool/SoundEffect';
import * as i18n from 'db://i18n/LanguageData';
const { ccclass, property } = _decorator;

/**
 * Predefined variables
 * Name = SoltaireGame
 */
 
@ccclass('SoltaireGame')
export class SoltaireGame extends Component {
    static instance:SoltaireGame=null!

    @property(Node)
    cardClon: Node= null!;

    @property(SpriteFrame)
    numberSF: SpriteFrame[] = [];

    @property(PlayGroup)
    playGroup: PlayGroup= null!;

    @property(PlayGroupAi)
    playGroupAis: PlayGroupAi[]= [];

    @property(CardGroupParent)
    playGroupAll: CardGroupParent[]= [];

    @property(Label)
    tipLabel: Label= null!;

    @property(Label)
    allScoreNumLabel: Label= null!;

    inputNode:Node;
    dealBtn:Node;
    chuScore:Node;
    interchangeCard:Node;
    

    chupaiNull:Node;
    chupai:Node;
    pass:Node;
    interchange:Node;

    imgTips:Node;
    round:Label;

    ScreenOrientation=1;//1：竖屏
    onLoad()
    {
        if (GameManager.Instance.GetScreenOrientation()==0) {
            this.ScreenOrientation=0;
        }else
        {
            this.ScreenOrientation=1;
        }
        
        SoltaireGame.instance=this;
        this.inputNode=this.node.getChildByPath("input");
        this.dealBtn=this.node.getChildByPath("deal");
        this.chuScore=this.node.getChildByPath("chuScore");
        this.interchangeCard=this.node.getChildByPath("interchangeCard");


        this.chupaiNull=this.node.getChildByPath("chupaiNull");
        this.chupai=this.node.getChildByPath("chupai");
        this.pass=this.node.getChildByPath("pass");
        
        this.interchange=this.node.getChildByPath("interchange");
        this.imgTips=this.node.getChildByPath("imgTips");

    }
    
    start () {
        GameManager.Instance.adaptation();

        //this.InitCard();
        //this.node.getChildByPath("difficult").active=true;
        //this.ClickPlay();

        this.ClickSelectDifficult(null,GameManager.Instance.difficult);
        //this.scheduleOnce(this.GameWin,1);
    }

    ClickSelectDifficult(event: Event, customEventData: number)
    {
        this.seleceDiff=this.difficult;

        this.InitCard();
        this.InitLevelData();
    }

    seleceDiff=[];
    //难度卡牌
    difficult=[101,102,103,104,105,106,107,108,109,110,111,112,113,201,202,203,204,205,206,207,208,209,210,211,212,213,301,302,303,304,305,306,307,308,309,310,311,312,313,401,402,403,404,405,406,407,408,409,410,411,412,413];
    public RetrueRandomCard():number
    {
        let rD=GameFun.randomInt(0,this.seleceDiff.length);
        let cD=this.seleceDiff[rD];
        this.seleceDiff.splice(rD,1);
        return cD;
    }
    
    //初始化卡牌
    InitCard()
    {
        let randaAll=[];
        for (let index = 0; index < 6; index++) {
            let groud=[]
            for (let y = 0; y < 5; y++) {
                let rD=GameFun.randomInt(0,this.seleceDiff.length);
                let cD=this.seleceDiff[rD];
                groud.push(cD);
                this.seleceDiff.splice(rD,1);
            }
            randaAll.push(groud);
        }
        // for (let i = 0; i < 3; i++) {
        //     let rD=GameFun.randomInt(0,this.seleceDiff.length);
        //     let cD=this.seleceDiff[rD];
        //     randaAll[i].push(cD);
        //     this.seleceDiff.splice(rD,1);
        // }

        let rD=GameFun.randomInt(0,randaAll.length);
        let playdata=randaAll[rD];
         //playdata=[101,501,107,108,211,301,302,303,304,305,212];
        randaAll.splice(rD,1);

        for (let i = 0; i < playdata.length; i++) {
            const element = playdata[i];
            let ca = instantiate(this.cardClon);
            this.playGroup.cardsNode.addChild(ca);
            ca.active=true;
            ca.worldPosition=this.dealBtn.worldPosition;
            let card= ca.getComponent(Card);
            card.Init(element,this.playGroup);
            let end=v3(-10+97.2*i,0,0);
            card.MoveGroupTurnoverCard(i*0.05,end);
            this.playGroup.AddOneCard(card);
            this.playGroup.cardIsShow=true;
            card.isTouch=true;
        }
        this.playGroupAll.push(this.playGroup);

        SoundEffect.instance.playOneShotName("card_kubaru");

        for (let k = 0; k < this.playGroupAis.length; k++) {
            const pg = this.playGroupAis[k];
            rD=GameFun.randomInt(0,randaAll.length);
            playdata=randaAll[rD];
            randaAll.splice(rD,1);
    
            for (let i = 0; i < playdata.length; i++) {
                const element = playdata[i];
                let ca = instantiate(this.cardClon);
                pg.cardsNode.addChild(ca);
                ca.active=true;
                ca.worldPosition=this.dealBtn.worldPosition;
                let card= ca.getComponent(Card);
                card.Init(element,pg);
                let end=v3(15*i,0,0);
                card.MoveGroup(i*0.05,end);
                //card.MoveGroupTurnoverCard(i*0.05,end);
                pg.AddOneCard(card);
            }

            this.playGroupAll.push(pg);
        }

        // this.scheduleOnce(()=>{
        //     this.playGroup.SortCards();
        //     this.playGroup.PositionSort();
        //     for (let i = 0; i < this.playGroupAis.length; i++) {
        //         this.playGroupAis[i].SortCards();
        //         this.playGroupAis[i].PositionSort();
        //     }
        // },1.6);

        this.scheduleOnce(()=>{
            this.OnePlayCard();
        },1.2);

        //this.ShowInput(2.3);
        this.ShowInputTouch(true);
    }

    menoyLabel:Label;
    InitLevelData()
    {
        this.menoyLabel=this.playGroup.node.getChildByPath("menoy/num").getComponent(Label)
        this.menoyLabel.string=LocalStorageMgr.Instance.GetItemInt("gold",300000).toString();
        this.UpdataAllScore(GameManager.Instance.difficult*120);
    }

    //更新总分
    allScoreNum=0;
    public UpdataAllScore(addScore )
    {
        this.allScoreNum+=addScore;
        this.allScoreNumLabel.string=this.allScoreNum.toString();
    }

    public AddMenoy(num:number)
    {
        let goldNum= LocalStorageMgr.Instance.GetItemInt("gold",300000);
        LocalStorageMgr.Instance.SetItem("gold",goldNum+num);
        this.UpdataMenoy();
    }

    public UpdataMenoy()
    {
        this.menoyLabel.string=LocalStorageMgr.Instance.GetItemInt("gold",300000).toString();
    }

    //屏蔽点击
    // ShowInput(time=0.25)
    // {
    //     this.inputNode.active=true;
    //     this.scheduleOnce(()=>{
    //         this.inputNode.active=false;
    //     },time);
    // }

    ShowInputTouch(isI:boolean)
    {
        this.inputNode.active=isI;
    }

    startPlayCard=0;//第一个出牌人
    //第一次出牌
    OnePlayCard()
    {
        let rTakeId= randomRangeInt(0,6);//随机出牌组
        //rTakeId=0;
        this.startPlayCard=rTakeId;
        this.TakeTurnsPlayCard(rTakeId);
    }

    NaxtTakeTurnsPlayCard(id:number,time:number=0.5)
    {
        this.playGroupAll[id].SetInfoSelet(false);
        if (id==5) 
        {
            this.scheduleOnce(()=>{
                this.TakeTurnsPlayCard(0);
            },time);
            if (this.playGroupAll[0].cardIsOver==false) {
                this.playGroupAll[0].tipsNode.active=false;
            }
        }else
        {
            this.scheduleOnce(()=>{
                this.TakeTurnsPlayCard(id+1);
            },time);
            if (this.playGroupAll[id+1].cardIsOver==false) {
                this.playGroupAll[id+1].tipsNode.active=false;
            }
        }


    }
    
    gameType=0;//三个阶段，前补分，中换牌，后补分
    gameLapCount=0;//累加次数
    //轮巡出牌
    TakeTurnsPlayCard(id:number)
    {
        if (this.gameOver) {
            return;
        }
        
        //console.log(GameAllData.Instance.lastPlays);
        if (this.playGroupAll[id].cardIsOver==true) {
            if (id==5) {
                SoltaireGame.instance.TakeTurnsPlayCard(0);
                if (this.startPlayCard==id) this.startPlayCard=0;
            }else
            {
                SoltaireGame.instance.TakeTurnsPlayCard(id+1);
                if (this.startPlayCard==id) this.startPlayCard=id+1;
            }
            return;
        }

        let havePlay=0;
        for (let i = 0; i < 6; i++) {
            if (this.playGroupAll[i].cardIsOver==false) {
                havePlay++;
            }
        }

        if (havePlay==1) {
            this.gameOver=true;
            this.scheduleOnce(()=>{
                SoundEffect.instance.playOneShotName("win");
                this.GameOver();
            },0.5)
            return;
        }

        if (this.startPlayCard==id) {
            if (this.gameType==0||this.gameType==1) {
                if (this.playGroupAll[id].curScore==GameAllData.Instance.lastPlayUpScore) {
                    this.gameType++;
                    this.gameLapCount=0;
                }else
                {
                    let count=2;
                    if (havePlay<=3) {
                        count=3;
                    }

                    this.gameLapCount++;
                    if (this.gameLapCount>=count) {
                        this.gameType++;
                        this.gameLapCount=0;
                        
                        for (let i = 0; i <6; i++) {
                            this.playGroupAll[i].scoreNode.active=false;
                        }
                    }
                }
            }else  if (this.gameType==2)
            {//交换
                this.gameType++;
                this.gameLapCount=0;
            }else
            {
                if (this.playGroupAll[id].curScore==GameAllData.Instance.lastPlayUpScore) {
                    //结束
                    this.gameType++;
                    this.gameLapCount=0;
                }else
                {
                    let count=2;
                    if (havePlay<=3) {
                        count=3;
                    }

                    this.gameLapCount++;
                    if (this.gameLapCount>=count) {
                        //结束
                        this.gameType++;
                        this.gameLapCount=0;
                    }
                }
            }

        }  

        if (this.gameType==0) {
            this.gameType=1;
        }

        if (this.gameType==1) {
            if (id==0) {
                this.ShowChuScore();
                this.ShowPlayTips(i18n.t("tips1"));

            }else{
                this.playGroupAis[id-1].SetInfoSelet(true);
                this.playGroupAis[id-1].AiSelectChuScore();
            }
        }else if (this.gameType==2)
        {//第四轮交换卡牌
            if (id==0) {
                this.ShowPlayTips(i18n.t("tips2"));
                this.ShowInterchangeCard();
            }else{
                this.playGroupAis[id-1].SetInfoSelet(true);
                this.playGroupAis[id-1].AiSelectInterchangeCard();
            }
        }else if (this.gameType==3)
        {//
            if (id==0) {
                this.ShowChuScore();
            }else{
                this.playGroupAis[id-1].SetInfoSelet(true);
                this.playGroupAis[id-1].AiSelectChuScore2();
            }
        }else 
        {//结束比大小
            for (let i = 0; i < this.playGroupAis.length; i++) {
                const element = this.playGroupAis[i];
                if (element.cardIsOver) {
                    continue;
                }

                for (let j = 0; j < element.cards.length; j++) {
                    element.cards[j].ShowCard();
                }

                element.tipsNode.active=false;
                element.scoreNode.active=false;
            }
            this.gameOver=true;

            this.scheduleOnce(()=>{
                SoundEffect.instance.playOneShotName("win");
                this.GameOver();
            },0.5)
        }

    }

    //选择弃牌，跟分，加分
    private ShowChuScore()
    {
        this.playGroup.SetInfoSelet(true);
        this.chuScore.active=true;     
    }

    //选择弃牌
    public ClickPlaySelectPass()
    {
        this.chuScore.active=false;
        this.playGroup.SelectPass();
        this.NaxtTakeTurnsPlayCard(0);
        this.ShowPlayTips("");
    }

    //跟分
    public ClickPlaySelectGen()
    {
        this.chuScore.active=false;
        if (GameAllData.Instance.lastPlayUpScore==0) {
            this.playGroup.SelectGen(100*GameManager.Instance.difficult);
        } else {
            this.playGroup.SelectGen(GameAllData.Instance.lastPlayUpScore);
        }
        this.NaxtTakeTurnsPlayCard(0);
        this.ShowPlayTips("");
    }

    //加分
    public ClickPlaySelectAdd100()
    {
        this.chuScore.active=false;
        if (GameAllData.Instance.lastPlayUpScore==0) {
            this.playGroup.SelectAdd100(200*GameManager.Instance.difficult);
        } else {
            this.playGroup.SelectAdd100(GameAllData.Instance.lastPlayUpScore+100*GameManager.Instance.difficult);
        }
        this.NaxtTakeTurnsPlayCard(0);
        this.ShowPlayTips("");
    }
   
    //选择交换卡牌
    private ShowInterchangeCard()
    {
        this.interchangeCard.active=true;
        this.ShowInputTouch(false);
    }

    //点击交换
    public ClickPlayInterchangeCard()
    {
        this.playGroup.SelectInterchangeCard();
        this.interchangeCard.active=false;
        this.ShowInputTouch(true);
        this.NaxtTakeTurnsPlayCard(0,2);
    }

    //显示步骤提示
    private ShowPlayTips(str)
    {
        this.tipLabel.string=str;
    }

    //卡牌比较 cA>cB 返回true
    CompareCard(cA:CardGroupParent,cB:CardGroupParent)
    {
        let HandsA= cA.GetPokerHands();
        let HandsB= cB.GetPokerHands();

        if (HandsA<HandsB) {
            return true;
        }else if (HandsA>HandsB){
            return false;
        }else
        {
            let sortA= cA.GetSortCards();
            let sortB= cB.GetSortCards();
            if (HandsA==1||HandsA==4||HandsA==5)
            {
                if (sortA[4].cardNumber>=sortB[4].cardNumber) 
                {
                    return true;
                }else
                {
                    return false;
                }
            }

            let fourA=0;
            let fourB=0;

            let threeA=0;
            let threeB=0;

            let cardNumA=[0,0,0,0,0,0,0,0,0,0,0,0,0]; 
            let cardNumB=[0,0,0,0,0,0,0,0,0,0,0,0,0]; 
            for (let i = 0; i < 5; i++) {
                const cardA = sortA[i];
                cardNumA[cardA.cardNumber-1]++;

                const cardB = sortB[i];
                cardNumB[cardB.cardNumber-1]++;
            }
    
            for (let i = 0; i < cardNumA.length; i++) {
                if (cardNumA[i]==4) {
                    fourA=i;
                }
                if (cardNumB[i]==4) {
                    fourB=i;
                } 

                if (cardNumA[i]==3) {
                    threeA=i;
                }
                if (cardNumB[i]==3) {
                    threeB=i;
                } 
            }

            if (HandsA==2)
            {
                if (fourA>fourB) {
                    return true;
                }else
                {
                    return false;
                }
            }

            if (HandsA==3||HandsA==6)
            {
                if (threeA>threeB) {
                    return true;
                }else
                {
                    return false;
                }
            }

            if(HandsA==7)
            {
                let twoA=[];
                let twoB=[];
                let oneA=0;
                let oneB=0;

                for (let i = 0; i < cardNumA.length; i++) 
                {
                    if (cardNumA[i]==2) {
                        twoA.push(i)
                    }
                    if (cardNumB[i]==2) {
                        twoB.push(i)
                    } 
    
                    if (cardNumA[i]==1) {
                        oneA=i;
                    }
                    if (cardNumB[i]==1) {
                        oneB=i;
                    }                    
                }

                if (twoA[1]>twoB[1]) 
                    {
                        return true
                    }else if (twoA[1]<twoB[1]) 
                    {
                        return false
                    }else
                    {
                        if (twoA[0]>twoB[0]) 
                        {
                            return true
                        }else if (twoA[0]<twoB[0]) 
                        {
                            return false
                        }else
                        {
                            if (oneA>=oneB) 
                            {
                                return true
                            }else 
                            {
                                return false
                            }
                        }
                    }
            }

            if(HandsA==8)
            {
                let twoA=0;
                let twoB=0;
                let oneA=[];
                let oneB=[];

                for (let i = 0; i < cardNumA.length; i++) 
                {
                    if (cardNumA[i]==2) {
                        twoA=i;
                    }
                    if (cardNumB[i]==2) {
                        twoB=i;
                    } 
    
                    if (cardNumA[i]==1) {
                        oneA.push(i);
                    }
                    if (cardNumB[i]==1) {
                        oneB.push(i);
                    } 
                }

                if (twoA>twoB) 
                {
                    return true
                }else if (twoA<twoB) 
                {
                    return false
                }else
                {
                    for (let j = 2; j >=0; j--)
                    {
                        if (oneA[j]>oneB[j]) {
                            return true;
                        }else if (oneA[j]<oneB[j]) {
                            return false;
                        }
                    }

                    return true;
                }
            }

            if(HandsA==9)
            {
                let oneA=[];
                let oneB=[];

                for (let i = 0; i < cardNumA.length; i++) 
                {
                    if (cardNumA[i]==1) {
                        oneA.push(i);
                    }
                    if (cardNumB[i]==1) {
                        oneB.push(i);
                    } 
                }

                for (let j = 4; j >=0; j--)
                {
                    if (oneA[j]>oneB[j]) {
                        return true;
                    }else if (oneA[j]<oneB[j]) {
                        return false;
                    }
                }
                return true;
            }
        }
    }

    gameOver=false;
    GameOver()
    {
        this.ShowPlayTips(i18n.t("tips3"));

        let cardAll:CardGroupParent[]=[];
        for (let i = 0; i < 6; i++) {
            const element = this.playGroupAll[i];
            if (element.cardIsOver) {
                element.tipsNode.active=false;
                element.scoreNode.active=false;
            }else
            {
                cardAll.push(element);
            }    
        }

        let maxCard=cardAll[0];

        for (let k = 1; k < cardAll.length; k++) {
            const element = cardAll[k];
            if (this.CompareCard(maxCard,element)) 
            {
                element.scoreNode.active=false;
                element.tipsNode.active=true;
                element.ShowTipsLabel(i18n.t("pockName"+element.GetPokerHands()));
            }else
            {
                maxCard.scoreNode.active=false;
                maxCard.tipsNode.active=true;
                maxCard.ShowTipsLabel(i18n.t("pockName"+maxCard.GetPokerHands()));
                maxCard=element;
            }
        }
        
        maxCard.tipsNode.active=true;
        maxCard.ShowTipsLabel(i18n.t("pockName"+maxCard.GetPokerHands()));
        maxCard.scoreNode.active=true;
        maxCard.scoreLabel.string="+"+this.allScoreNum;
        maxCard.scoreLabel.color=Color.YELLOW;

        if (maxCard==this.playGroup) 
        {
            this.AddMenoy(this.allScoreNum);
        }

        this.allScoreNumLabel.string="0";

        this.node.getChildByName("Replay").active=true;
    }

    ClickReplay()
    {
        this.gameType=0;
        this.gameLapCount=0;
        GameAllData.Instance.ClearCurGameData();
        if (SoltaireGame.instance.ScreenOrientation==1) {
            director.loadScene("gameH");
        }else
        {
            director.loadScene("gameW");
        }
    }

    ClickMain()
    {
        this.gameType=0;
        this.gameLapCount=0;
        GameAllData.Instance.ClearAllGameData();
        if (SoltaireGame.instance.ScreenOrientation==1) {
            director.loadScene("homeH");
        }else
        {
            director.loadScene("homeW");
        }
    }

    cardPClone:Node;
    cardP:Node;
    CreateEffect()
    {
        let size = view.getVisibleSize();
        let ca = instantiate(this.cardPClone);
        this.cardP.addChild(ca);
        ca.active=true;
        ca.scale=v3(0.5,0.5,0.5);
        let sp= ca.getComponent(Sprite);
        sp.spriteFrame=this.numberSF[randomRangeInt(0,this.numberSF.length-1) ]
        ca.position=v3(randomRangeInt(-size.width/2,size.width/2),0);
        tween(ca).parallel(
            tween().by(2, {position:v3(0,-size.height/2,0)},{easing: "quadOut"})
            ,tween().to(0.5, { scale: v3(1,1,1)})
        )
        .by(4, {position:v3(0,size.height+500,0)})
        .start()
    }
}

